package day40.edu;

import org.junit.Test;

import java.lang.reflect.*;

// Created: 10/15/2025, ChangJiang Ru
public class ReflectionTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<Person> clazz = Person.class;
        Person p1 = clazz.newInstance();

        System.out.println(p1);

        // call the field
        Field ageField = clazz.getField("age");
        ageField.set(p1, 10);
        System.out.println(ageField.get(p1));

        // invoke the method
        Method showMethod = clazz.getMethod("show");
        showMethod.invoke(p1);
    }
    
    @Test
    public void test1() throws Exception {
        Class clazz = Person.class;
        Constructor cons = clazz.getDeclaredConstructor(String.class, int.class);
        cons.setAccessible(true);
        Person p1 = (Person)cons.newInstance("Tom", 12);
        System.out.println(p1);

        // call the field of private
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(p1, "Jerry");

        System.out.println(nameField.get(p1));

        Method showMethod = clazz.getDeclaredMethod("showNation", String.class);
        showMethod.setAccessible(true);
        String info = (String)showMethod.invoke(p1, "ChN");
        System.out.println(info);

    }

    @Test
    public void test2() throws InstantiationException, IllegalAccessException {
        Class clazz = Person.class;
        Person per = (Person)clazz.newInstance();

        System.out.println(per);
    }
    
    @Test
    public void test3() throws ClassNotFoundException {
        Class clazz = Class.forName("day40.edu.Person");
        Class superClazz = clazz.getSuperclass();
    }
    
    @Test
    public void test4() throws ClassNotFoundException {
        Class clazz = Class.forName("day40.edu.Person");
        Type superClass = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) superClass;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
//        System.out.println((Class)actualTypeArguments[0].getName());
    }
}
